package gsd.gaudi.client;

import gsd.gaudi.common.GaudiGuiHierarchy;

import java.awt.Component;
import java.awt.Container;
import java.awt.Window;
import java.lang.reflect.Method;
import java.util.Arrays;


/**
 * The class used to warp a launch and execution of a target application being monitored
 * by the GaudiClient.
 * 
 * @author nunocoracao
 *
 */
public class Launcher {

	private String mainclass;
	private String[] args;
	
	private Thread t;
	
	/**
	 * Launcher's constructor, it creates a represantation of the target application which
	 * can be launched.
	 * @param mc - Name of the class within the target application which has the main method.
	 * @param args - Arguments to pass to the target application
	 */
	public Launcher(String mc, String[] args){
		this.mainclass = mc;
		int i = 0;
		for(String s : args){
			if(s.equals(mc))
				break;
			i++;
		}
		this.args = Arrays.copyOfRange(args, i, args.length);
	}
	
	/**
	 * Method used to launch the target application warped inside GaudiClient.
	 * <p>
	 * The method creates a new Thread which runs the target application.
	 */
	@SuppressWarnings("unchecked")
	public void launch(){
		
		this.t = new Thread(new Runnable(){

			@Override
			public void run() {
				try 
				{
					Class<?> c = Class.forName(mainclass);
					Class[] argTypes = new Class[] { String[].class };
					Method main = c.getDeclaredMethod("main", argTypes);
					String[] mainArgs = Arrays.copyOfRange(args, 0, args.length);
					main.invoke(null, (Object)mainArgs);	
				} catch (Exception x) {
					x.printStackTrace();
				}	
			}
		});
		
		this.t.start();
	}

	public void closeGuiApp(GaudiGuiHierarchy h) {
		for(Component c : h.getRegisterW2K().keySet()){
			if(c != null && c instanceof Window){
				((Window)c).dispose();
			}
		}

		Thread[] l = new Thread[100];
		int n = Thread.enumerate(l);

		for (int i=0; i<n; i++) {
			if (l[i].getName().contains("AWT-Windows")) {
				l[i].interrupt();
			}
		}

	}
	
	
}